home *** CD-ROM | disk | FTP | other *** search
- /* Plot3DView.m Copyright 1992 Steve Ludtke */
- /* This view allows the display of 3d functions with real time rotation */
-
- #import "Plot3DView.h"
- #import "PlotShape.h"
- #import "PControl.h"
- #import <appkit/appkit.h>
- #import <3Dkit/3Dkit.h>
- #import <dpsclient/event.h>
- #import <dpsclient/psops.h>
- #import <stdio.h>
- #import <math.h>
- #include <libc.h>
- #import "Expression.h"
- #import "DensView.h"
-
- void PSsethel(); /* makes Helvetica current font */
-
- #define LRAD 10.0
-
- extern id NXApp;
-
- float rnd0(float x) { if (x<0) return(ceil(x)); else return floor(x); }
-
- @implementation Plot3DView
- -initFrame:(NXRect *)myrect
- {
- int i,j,ddl;
- RtPoint fromP = {0,0,6.0}, toP = {0,0,0};
- RtPoint lFromP = {5.0,10.0,5.0},lToP = {0,0,0};
- RtMatrix mx = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.0 };
- id aShader;
- char home[60];
-
- [super initFrame:(NXRect *)myrect];
-
- [self setBackgroundColor:NX_COLORWHITE];
- [self setDrawBackgroundColor:YES];
-
- [self setEyeAt:fromP toward:toP roll:0.0];
-
- mx[0][0]=mx[1][1]=mx[2][2]=3.0/fromP[2];
- [self setPreTransformMatrix:mx];
-
- aShader=[[N3DShader alloc] init];
- [(N3DShader *)aShader setShader:"matte"];
-
- shape=[[PlotShape alloc] init];
- [(N3DShape *) shape setShader:aShader];
- [shape scale:-1.0 :1.0 :1.0];
- [[self setWorldShape:shape] free];
-
- ambLight=[[N3DLight alloc] init];
- [ambLight makeAmbientWithIntensity:0.2];
- [self addLight:ambLight];
- ambient=0.2;
-
- ltheta=.785;
- lchi=-.785;
- aLight=[[N3DLight alloc] init];
- lFromP[0]= LRAD*sin(lchi)*cos(ltheta);
- lFromP[2]= LRAD*cos(lchi)*cos(ltheta);
- lFromP[1]= LRAD*sin(ltheta);
- [aLight makeDistantFrom:lFromP to:lToP intensity:0.8];
- [self addLight:aLight];
-
- Rmode=3;
-
- ddl=[Window defaultDepthLimit];
- if (ddl==NX_TwoBitGrayDepth||ddl==NX_EightBitGrayDepth) ddl=0;
- else ddl=1;
-
-
- /* initialize preferences */
- for (i=0; i<MAXSETS; i++) {
- pref[i].ndata=0;
- pref[i].sym= -1;
-
- if (ddl) {
- pref[i].mapcol[0][0]=0.0;
- pref[i].mapcol[0][1]=0.0;
- pref[i].mapcol[0][2]=0.5;
-
- pref[i].mapcol[1][0]=0.7;
- pref[i].mapcol[1][1]=0.0;
- pref[i].mapcol[1][2]=0.7;
-
- pref[i].mapcol[2][0]=1.0;
- pref[i].mapcol[2][1]=0.0;
- pref[i].mapcol[2][2]=0.0;
-
- pref[i].mapcol[3][0]=1.0;
- pref[i].mapcol[3][1]=0.3;
- pref[i].mapcol[3][2]=0.0;
-
- pref[i].mapcol[4][0]=1.0;
- pref[i].mapcol[4][1]=1.0;
- pref[i].mapcol[4][2]=0.0;
- }
- else {
- for (j=0; j<5; j++) {
- pref[i].mapcol[j][0]=pref[i].mapcol[j][1]=pref[i].mapcol[j][2]=
- .5+(float)j/10.0;
- }
- }
-
- for (j=0; j<5; j++) pref[i].mapsel[j]=1;
- pref[i].mapmode=1;
-
- pref[i].fileData=pref[i].Sdata=NULL;
- pref[i].expr=[[Expression alloc] init];
- [pref[i].expr parse:"0"];
- pref[i].nx=pref[i].ny=10;
- }
- /* initial function to display */
- pref[0].sym=5;
- pref[0].nx=pref[0].ny=40;
- [pref[0].expr parse:"cos(sqrt(x^2+y^2)+2*pi*t)/sqrt((x+a)^2+y^2+1)"];
-
- /* start spinning, all angles in radians */
- chi=.2;
- theta=.433;
- /*dchi=0.025;*/
- dchi=0.0;
- initflag=1;
- Rflags=RF_axis+RF_persp;
- Omode=0;
- aspect=1.0;
- [shape setOver:Omode];
-
- if (ddl) {
- flagcol[0][0]=flagcol[4][0]=0.0;
- flagcol[0][1]=flagcol[4][1]=0.0;
- flagcol[0][2]=flagcol[4][2]=1.0;
- flagcol[1][0]=flagcol[2][0]=1.0;
- flagcol[1][1]=flagcol[2][1]=1.0;
- flagcol[1][2]=flagcol[2][2]=1.0;
- flagcol[3][0]=0.0;
- flagcol[3][1]=1.0;
- flagcol[3][2]=0.0;
- }
- else {
- flagcol[0][0]=flagcol[4][0]=0.5;
- flagcol[0][1]=flagcol[4][1]=0.5;
- flagcol[0][2]=flagcol[4][2]=0.5;
- flagcol[1][0]=flagcol[2][0]=1.0;
- flagcol[1][1]=flagcol[2][1]=1.0;
- flagcol[1][2]=flagcol[2][2]=1.0;
- flagcol[3][0]=0.0;
- flagcol[3][1]=0.0;
- flagcol[3][2]=0.0;
- }
- [shape setFlagColors:flagcol];
-
- [[[NXApp printInfo] setVertCentered:YES] setOrientation:NX_PORTRAIT andAdjust:YES];
- [[NXApp printInfo] setMarginLeft:0.0 right:0.0 top:0.0 bottom:0.0];
- [[NXApp printInfo] setHorizPagination:NX_FITPAGINATION];
- [[NXApp printInfo] setVertPagination:NX_FITPAGINATION];
-
- timer=(DPSTimedEntry)DPSAddTimedEntry(TIMESTEP,itstime,self,NX_RUNMODALTHRESHOLD);
- [self zoom:self];
-
- if (getenv("USER")!=NULL) {
- sprintf(home,"/tmp/%s",getenv("USER"));
- mkdir(home,0777);
- }
-
- return self;
- }
-
- /* fix the scaling after being resized */
- -superviewSizeChanged:(const NXSize *)oldsize
- {
- [super superviewSizeChanged:oldsize];
- [self zoom:self];
- return self;
- }
-
- -free
- {
- DPSRemoveTimedEntry(timer);
- [super free];
- return self;
- }
-
- -drawPS:(NXRect *)myrect :(int)rectCount
- {
- char s[80],t[20];
- int i,n,xyz[61];
- float x,y,xpm,ypm,pv[61];
- RtPoint pnt[61];
-
- if (bounds.size.width<150) return self;
- /* display alt and az in upper right corner */
- PSsetgray(0.0);
- PSsethel();
- sprintf(s,"Alt:%6.2f Az:%6.2f",theta*57.295787,chi*57.295787);
- PSmoveto(bounds.size.width-100.0,bounds.size.height-15.0);
- PSshow(s);
- PSstroke();
-
- if (Rflags&RF_labels && Rmode<4) {
- if (chi>(M_PI/2.0)&&chi<(M_PI*1.5)) ypm=1.1;
- else ypm=-1.1;
- if (chi<M_PI) xpm=1.1;
- else xpm=-1.1;
-
- for (n=0,y=Tick0[0],x=Tick00[0]; x<1; y+=Tick1[0],x+=Tick01[0],n++) {
- if (n>59) n=59;
- pnt[n][0]=x;
- pnt[n][1]=ypm;
- pnt[n][2]=-1.1;
- pv[n]=y;
- xyz[n]=0;
- }
- for (y=Tick0[1],x=Tick00[1]; x<1; y+=Tick1[1],x+=Tick01[1],n++) {
- if (n>59) n=59;
- pnt[n][1]=x;
- pnt[n][0]=xpm;
- pnt[n][2]=-1.1;
- pv[n]=y;
- xyz[n]=1;
- }
- for (y=Tick0[2],x=Tick00[2]; x<1; y+=Tick1[2],x+=Tick01[2],n++) {
- if (n>59) n=59;
- pv[n]=y;
- pnt[n][2]=x;
- if ((chi>M_PI/4.0&&chi<M_PI*.75)||(chi>M_PI*1.25&&chi<M_PI*1.75))
- { pnt[n][1]=ypm; pnt[n][0]=-xpm; }
- else { pnt[n][1]=-ypm; pnt[n][0]=xpm; }
- xyz[n]=2;
- }
- pnt[n][0]=xpm/1.18; pnt[n][1]=ypm/1.18; pnt[n][2]=-1.0;
-
- [shape convertObjectPoints:pnt count:n+1 toCamera:self];
- x=pnt[n][0];
- for (i=0; i<n; i++) {
- if (i==0|| xyz[i]!=xyz[i-1])
- strcpy(t,[[tickpos cellAt:2 :xyz[i]] stringValue]);
- sprintf(s,t,pv[i]);
- if (pnt[i][0]<x) PSmoveto(pnt[i][0]-20.0,pnt[i][1]-5.0);
- else PSmoveto(pnt[i][0],pnt[i][1]-5.0);
- PSshow(s);
- }
- PSstroke();
- }
-
- return self;
- }
-
- /* recalculates and redisplays data */
- -zoom:sender
- {
- float x0,x1,xs,y0,y1,ys,xf,yf,zf;
- float z0,z1,x,y,z,zz,T,A,B,C,D;
- int i,j=0,k,cm,nc,color[5];
- id tmp;
-
- T=[[varT cellAt:0 :0] floatValue];
- A=[[varT cellAt:1 :0] floatValue];
- B=[[varT cellAt:2 :0] floatValue];
- C=[[varT cellAt:3 :0] floatValue];
- D=[[varT cellAt:4 :0] floatValue];
-
- /* calculate minima, maxima and step sizes */
- x0=minX;
- x1=maxX;
- y0=minY;
- y1=maxY;
-
- xf=(x1-x0)/2.0;
- yf=(y1-y0)/2.0;
-
- /* make sure there's enough space in the data array */
- for (i=0; i<NFN; i++) {
- if (pref[i].sym==-1 || pref[i].fileData!=NULL) continue;
- if (pref[i].ndata!=(pref[i].nx*pref[i].ny)) {
- if (pref[i].ndata!=0) { free(pref[i].data); free(pref[i].color); }
- pref[i].data=malloc(sizeof(Point)*(pref[i].nx*pref[i].ny+2));
- pref[i].color=malloc(sizeof(RtColor)*(pref[i].nx*pref[i].ny+2));
- pref[i].ndata=pref[i].nx*pref[i].ny;
- }
- }
- z0=MAXFLOAT;
- z1= -MAXFLOAT;
-
- /* calculate (function mode) or clip (file mode) the data */
- /* also finds min/max Z */
- for (i=0; i<NFN; i++) {
- if (pref[i].sym==-1) continue;
- tmp=pref[i].expr;
- [tmp setVar:"t" value:T];
- [tmp setVar:"a" value:A];
- [tmp setVar:"b" value:B];
- [tmp setVar:"c" value:C];
- [tmp setVar:"d" value:D];
-
- /* FILE MODE */
- if (pref[i].fileData!=NULL) {
- k=0;
- for (j=0; j<pref[i].nfdata; j++) {
- if (pref[i].fileData[j].x>x1||pref[i].fileData[j].x<x0||
- pref[i].fileData[j].y>y1||pref[i].fileData[j].y<y0) continue;
- pref[i].data[k].x=(pref[i].fileData[j].x-x0)/xf-1.0;
- [tmp setVar:"x" value:pref[i].data[k].x];
- pref[i].data[k].y=(pref[i].fileData[j].y-y0)/yf-1.0;
- [tmp setVar:"y" value:pref[i].data[k].y];
- [tmp setVar:"z" value:pref[i].fileData[j].z];
- pref[i].data[k].z=[tmp resultValue];
- if (pref[i].data[k].z>z1) z1=pref[i].data[k].z;
- if (pref[i].data[k].z<z0) z0=pref[i].data[k].z;
- k++;
- }
- pref[i].ndata=k;
-
- if (pref[i].data[0].y!=pref[i].data[1].y) {
- pref[i].nx=pref[i].ny=(int)floor(sqrt((float)k));
- }
- else {
- for (j=1; j<k; j++) if (pref[i].data[j-1].y!=pref[i].data[j].y) break;
- pref[i].nx=j;
- pref[i].ny=k/j;
- }
- }
- /* FUNCTION MODE */
- else {
- xs=(maxX-x0)/(float)(pref[i].nx-1);
- ys=(maxY-y0)/(float)(pref[i].ny-1);
- x1=maxX+xs/2.0;
- y1=maxY+ys/2.0;
- j=0;
- for (y=y0; y<y1; y+=ys) {
- for (x=x0; x<x1; x+=xs) {
- pref[i].data[j].x=(x-x0)/xf-1.0;
- pref[i].data[j].y=(y-y0)/yf-1.0;
- [tmp setVar:"x" value:x];
- [tmp setVar:"y" value:y];
- zz=pref[i].data[j].z=[tmp resultValue];
- if (zz!=zz || zz<-MAXFLOAT || zz>MAXFLOAT)
- zz=pref[i].data[j].z=0;
- if (zz>z1) z1=zz;
- if (zz<z0) z0=zz;
- j++;
- }
- }
- }
- }
- if (z0==MAXFLOAT) return self;
-
- /* BOTH MODES */
- if (z1<=z0) { z1=z0+.001; z0-=.001; }
- /* allow the controller to override min/max Z */
- [controller minmaxZ:&z0 :&z1];
-
- /* tick spacing calculations */
- if ([autotick intValue]) {
- [self tickCalc:5.0 :x0 :x1 :&Tick0[0] :&Tick1[0]];
- [[tickpos cellAt:0 :0] setFloatValue:Tick1[0]];
- [[tickpos cellAt:1 :0] setFloatValue:Tick0[0]];
- [self tickCalc:5.0 :y0 :y1 :&Tick0[1] :&Tick1[1]];
- [[tickpos cellAt:0 :1] setFloatValue:Tick1[1]];
- [[tickpos cellAt:1 :1] setFloatValue:Tick0[1]];
- [self tickCalc:5.0 :z0 :z1 :&Tick0[2] :&Tick1[2]];
- [[tickpos cellAt:0 :2] setFloatValue:Tick1[2]];
- [[tickpos cellAt:1 :2] setFloatValue:Tick0[2]];
- }
- else {
- Tick1[0]=[[tickpos cellAt:0 :0] floatValue];
- Tick0[0]=[[tickpos cellAt:1 :0] floatValue];
- Tick1[1]=[[tickpos cellAt:0 :1] floatValue];
- Tick0[1]=[[tickpos cellAt:1 :1] floatValue];
- Tick1[2]=[[tickpos cellAt:0 :2] floatValue];
- Tick0[2]=[[tickpos cellAt:1 :2] floatValue];
- }
- Tick00[0]=(Tick0[0]-x0)/(x1-x0)*2.0-1.0;
- Tick01[0]=Tick1[0]/(x1-x0)*2.0;
- Tick00[1]=(Tick0[1]-y0)/(y1-y0)*2.0-1.0;
- Tick01[1]=Tick1[1]/(y1-y0)*2.0;
- Tick00[2]=(Tick0[2]-z0)/(z1-z0)*2.0-1.0;
- Tick01[2]=Tick1[2]/(z1-z0)*2.0;
- [shape setTicks:Tick00 :Tick01];
-
- zf=(z1-z0)/2.0;
- /* scale and clip Z */
- for (i=0; i<NFN; i++) {
- if (pref[i].sym==-1) continue;
-
- /* Spherical coordinates */
- if (pref[i].sym==6) {
- if (pref[i].Sdata!=NULL) free(pref[i].Sdata);
- pref[i].Sdata=malloc(sizeof(Point)*pref[i].ndata);
- for (k=0; k<pref[i].ndata; k++) {
- x=(pref[i].data[k].x+1.0)*xf+x0;
- y=(pref[i].data[k].y+1.0)*yf+y0;
- if (fabs(z0)>fabs(z1)) z=pref[i].data[k].z/fabs(z0);
- else z=pref[i].data[k].z/fabs(z1);
- if (z>1.0) z=1.0;
- if (z<-1.0) z=-1.0;
- pref[i].Sdata[k].x=z*cos(y)*sin(x);
- pref[i].Sdata[k].y=z*sin(y)*sin(x);
- pref[i].Sdata[k].z=z*cos(x);
- }
- }
-
- /* color info */
- cm=pref[i].mapmode;
- for (j=k=0; j<5; j++) if (pref[i].mapsel[j]) { color[k]=j; k++; }
- nc=k;
- if (nc<2) cm=0;
-
- for (k=0; k<pref[i].ndata; k++) {
- if (pref[i].data[k].z>z1) pref[i].data[k].z=z1;
- if (pref[i].data[k].z<z0) pref[i].data[k].z=z0;
- z=pref[i].data[k].z=(pref[i].data[k].z-z0)/zf-1.0;
- if (cm==1) {
- j=floor((z+1.0)/2.00001*(float)(nc-1));
- z=(z+1.0)/2.0*(float)(nc-1)-(float)j;
- pref[i].color[k][0]=z*pref[i].mapcol[color[j+1]][0]+
- (1.0-z)*pref[i].mapcol[color[j]][0];
- pref[i].color[k][1]=z*pref[i].mapcol[color[j+1]][1]+
- (1.0-z)*pref[i].mapcol[color[j]][1];
- pref[i].color[k][2]=z*pref[i].mapcol[color[j+1]][2]+
- (1.0-z)*pref[i].mapcol[color[j]][2];
- }
- }
- }
-
- /* display 3d plot */
- [shape setData:pref :Rmode :Rflags];
- [shape setAng:theta :chi :aspect :ambient];
- [self display];
- /* display density plot */
- [controller updDen:Tick00 :Tick01];
- return self;
- }
-
- /* obvious */
- -setAng:(float)alt :(float)az
- {
- theta=alt;
- chi=az;
- return self;
- }
-
- /* allows spinning and zooming with the mouse */
- -mouseDown:(NXEvent *)oevent
- {
- int oldMask,loop=1;
- float ix=0,iy=0,ix2=0,iy2=0;
- NXEvent *event,evs;
- long tm,tm2;
-
- evs=*oevent;
- oevent=&evs;
- [self convertPoint:&oevent->location fromView:nil];
- oevent->location.x=oevent->location.x/bounds.size.width*2.0-1.0;
- oevent->location.y=oevent->location.y/bounds.size.height*2.0-1.0;
- ix2=ix=oevent->location.x;
- iy2=iy=oevent->location.y;
- tm2=tm=oevent->time;
-
- oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
-
- while (loop) {
- event = [NXApp getNextEvent:(NX_LMOUSEUPMASK | NX_LMOUSEDRAGGEDMASK)];
- [self convertPoint:&event->location fromView:nil];
- event->location.x=event->location.x/bounds.size.width*2.0-1.0;
- event->location.y=event->location.y/bounds.size.height*2.0-1.0;
-
- switch (event->type) {
- case NX_LMOUSEUP:
- loop = 0;
- dchi=-(event->location.x-ix2)/(float)(event->time-tm2)*15.0;
- if (fabs(dchi)<.004) dchi=0.0;
- [shape setAng:theta :chi :aspect :ambient];
- [self display];
- break;
- case NX_LMOUSEDRAGGED:
- theta-=(event->location.y-iy)*3.0;
- chi-=(event->location.x-ix)*4.0;
- if (theta>M_PI/2.0) theta=M_PI/2.0;
- if (theta<-M_PI/2.0) theta=-M_PI/2.0;
- while (chi>2.0*M_PI) chi-=2.0*M_PI;
- while (chi<0.0) chi+=2.0*M_PI;
- ix2=ix;
- iy2=iy;
- tm2=tm;
- ix=event->location.x;
- iy=event->location.y;
- tm=event->time;
- [shape setAng:theta :chi :aspect :ambient];
- [self display];
- break;
- default:
- break;
- }
- }
- [window setEventMask:oldMask];
- return self;
- }
-
- /* function called by timer */
- void itstime(DPSTimedEntry entry,double now,id call)
- {
- [call step];
- return;
- }
-
- /* do one time step */
- -step
- {
- if (initflag) {
- /* first time, do initialization stuff */
- if (controller==nil) return self;
- [controller startup:pref];
- [self setSurfaceTypeForAll:N3D_SmoothSolids chooseHider:YES];
- [self zoom:self];
- initflag=0;
- }
- if (dchi==0.0) return self;
- chi+=dchi;
- while (chi>2.0*M_PI) chi-=2.0*M_PI;
- while (chi<0.0) chi+=2.0*M_PI;
- [shape setAng:theta :chi :aspect :ambient];
- [self display];
- return self;
- }
-
- -tickCalc:(float)n :(float)x0 :(float)x1 :(float *)min :(float *)spa
- {
- float s,e;
-
- s=(x1-x0)/n;
- e=floor(log10(s));
- if (s/pow(10.0,e)<3.0) s=floor(s/pow(10.0,e-1.0))*pow(10.0,e-1.0);
- else s=floor(s/pow(10.0,e))*pow(10.0,e);
- *min=(floor(x0/s)+1.0)*(s);
- *spa=s;
- return self;
- }
-
- /* new min/max values */
- -zoomTo:(float)minx :(float)miny :(float)maxx :(float)maxy
- {
- minX=minx;
- minY=miny;
- maxX=maxx;
- maxY=maxy;
- return self;
- }
-
- -(int)acceptsFirstMouse { return (YES); }
-
- -setcontroller:con
- {
- controller=con;
- return self;
- }
-
- /* allow user to pause spinning */
- -togFreeze:sender
- {
- static float Tdchi;
-
- if ([sender intValue]) {
- Tdchi=dchi;
- dchi=0.0;
- return self;
- }
- dchi=Tdchi;
- return self;
- }
-
- - renderSelf:(RtToken)context
- {
-
- return self;
- }
-
- -makeSMap:sender
- {
- FILE *out;
- char home[60],s[80];
- id image,rep;
- NXSize size = { 400.0,400.0 };
- NXStream *stream;
- float xs,ys,x,y,xpm,ypm,fs;
- int r;
-
- sprintf(home,"/tmp/%s",getenv("USER"));
- if (getenv("USER")==NULL) strcpy(home,"/tmp");
-
- /* write maps for axis labels */
- if (Rflags&RF_labels) {
- [window setTitle:"Generating Axis Label Maps"];
-
- if (chi>(M_PI/2.0)&&chi<(M_PI*1.5)) ypm=1.0;
- else ypm=-1.0;
- if (chi<M_PI) xpm=1.0;
- else xpm=-1.0;
-
- r=floor(chi/M_PI*4.0);
-
- image=[[NXImage alloc] initSize:&size];
- [image setCacheDepthBounded:NO];
- [image useCacheWithDepth:NX_TwentyFourBitRGBDepth];
- rep=[image lastRepresentation];
- [rep setAlpha:NO];
- [rep setNumColors:3];
- [image lockFocus];
- PSselectfont("Helvetica-Bold",fs=[fontSize floatValue]);
- PSsetrgbcolor(1.0,.95,1.0);
- PSmoveto(0,0);
- PSlineto(1.0,1.0);
- PSstroke();
-
- PSsetrgbcolor(0,0,0);
- strcpy(s,[[axisTitle cellAt:0 :0] stringValue]);
- PSstringwidth(s,&xs,&ys);
- PSmoveto((size.width-xs)/2.0,size.height/4.0-fs*2.0-10.0);
- PSshow(s);
- for (y=Tick0[0],x=Tick00[0]; x<1; y+=Tick1[0],x+=Tick01[0]) {
- sprintf(s,[[tickpos cellAt:2 :0] stringValue],y);
- PSstringwidth(s,&xs,&ys);
- if (ypm<0)
- PSmoveto((x+1.0)*size.width/2.0-xs/2.0-1.0,size.height/4.0-fs-6.0);
- else PSmoveto(size.width*(1.0-x)/2.0-xs/2.0-1.0,size.height/4.0-fs-6.0);
- PSshow(s);
- }
- PSstroke();
-
- strcpy(s,[[axisTitle cellAt:1 :0] stringValue]);
- PSstringwidth(s,&xs,&ys);
- PSmoveto((size.width-xs)/2.0,size.height/2.0-fs*2.0-10.0);
- PSshow(s);
- for (y=Tick0[1],x=Tick00[1]; x<1; y+=Tick1[1],x+=Tick01[1]) {
- sprintf(s,[[tickpos cellAt:2 :1] stringValue],y);
- PSstringwidth(s,&xs,&ys);
- if (xpm>0)
- PSmoveto((x+1.0)*size.width/2.0-xs/2.0-1.0,size.height/2.0-fs-6.0);
- else PSmoveto(size.width*(1.0-x)/2.0-xs/2.0-1.0,size.height/2.0-fs-6.0);
- PSshow(s);
- }
- PSstroke();
-
- PSgsave();
- strcpy(s,[[axisTitle cellAt:2 :0] stringValue]);
- PSstringwidth(s,&xs,&ys);
- PStranslate(size.width/2.0,size.height*3.0/4.0);
- if (r%2==1) PSrotate(180.0);
- PSmoveto(-xs/2.0,0.0);
- PSshow(s);
- PSstroke();
- PSgrestore();
- PSgsave();
- PSrotate(90.0);
- PStranslate(size.height/2.0,-size.width);
- for (y=Tick0[2],x=Tick00[2]; x<1; y+=Tick1[2],x+=Tick01[2]) {
- sprintf(s,[[tickpos cellAt:2 :2] stringValue],y);
- PSstringwidth(s,&xs,&ys);
- if (r%2==1)
- PSmoveto(size.height/2.0-xs-2.0,(x+1.0)*(size.width)/2.0-8.0);
- else PSmoveto(8.0,(x+1.0)*(size.width)/2.0-8.0);
- PSshow(s);
- }
- PSstroke();
- PSgrestore();
- [image unlockFocus];
- stream=NXOpenMemory(NULL,0,NX_WRITEONLY);
- [image writeTIFF:stream];
- sprintf(s,"%s/plot3dxyz.tiff",home);
- NXSaveToFile(stream,s);
- NXClose(stream);
- [image free];
-
- sprintf(s,"%s/plot3d.rib",home);
- out=fopen(s,"w");
- fprintf(out,"MakeTexture \"%s/plot3dxyz.tiff\" \"%s/plot3dxyz.tx\" \"clamp\" \"black\" \"box\" 1 1\n",home,home);
- fclose(out);
- sprintf(s,"/usr/prman/prman %s/plot3d.rib",home);
- system(s);
- [window setTitle:"3D"];
- }
-
- if (Omode==0||Omode==OVER_csurf) return self;
- [window setTitle:"Generating Surface Map"];
-
- /* make map of contour/density plot */
- [controller dumpContour];
- sprintf(s,"%s/plot3d.rib",home);
- out=fopen(s,"w");
- fprintf(out,"MakeTexture \"%s/plot3d.tiff\" \"%s/plot3d.tx\" \"black\" \"black\" \"gaussian\" 1.8 1.8\n",home,home);
- fclose(out);
- sprintf(s,"/usr/prman/prman %s/plot3d.rib",home);
- system(s);
- [window setTitle:"3D"];
- return self;
- }
-
- - dumpRib:sender
- {
- static id savePanel=nil;
- NXStream *ts;
- char buf[MAXPATHLEN+1];
-
- if (!savePanel) {
- savePanel=[SavePanel new];
- [savePanel setRequiredFileType:"rib"];
- }
-
- Rmode+=4;
- [shape setData:pref :Rmode :Rflags];
-
- if([savePanel runModal]){
- [self makeSMap:self];
- ts=NXOpenMemory(NULL, 0, NX_WRITEONLY);
- strcpy(buf, [savePanel filename]);
- strrchr(buf,'.')[0]='\0';
- NXPrintf(ts, "Display \"%s.tiff\" \"file\" \"rgba\"\n", buf);
- [self copyRIBCode:ts];
- NXSaveToFile(ts, [savePanel filename]);
- NXCloseMemory(ts,NX_FREEBUFFER);
- }
-
- Rmode-=4;
- [shape setData:pref :Rmode :Rflags];
- return self;
- }
-
- -PRTiff:sender
- {
- static id savePanel=nil;
-
- if (!savePanel) {
- savePanel=[SavePanel new];
- [savePanel setRequiredFileType:"tiff"];
- }
-
- if([savePanel runModal]) [self renderTIFF:[savePanel filename]];
-
- return self;
- }
-
- - renderTIFF:(char *)fsp
- {
- NXStream *ts;
- char buf[MAXPATHLEN+1];
- char home[60];
-
- sprintf(home,"/tmp/%s",getenv("USER"));
- if (getenv("USER")==NULL) strcpy(home,"/tmp");
-
-
- Rmode+=4;
- [shape setData:pref :Rmode :Rflags];
-
- [self makeSMap:self];
- [window setTitle:"Rendering TIFF"];
- ts=NXOpenMemory(NULL, 0, NX_WRITEONLY);
- NXPrintf(ts, "Display \"%s\" \"file\" \"rgba\"\n", fsp);
- [self copyRIBCode:ts];
- sprintf(buf,"%s/plot3dp.rib",home);
- NXSaveToFile(ts, buf);
- NXCloseMemory(ts,NX_FREEBUFFER);
-
-
- [shape setData:pref :Rmode :Rflags];
- Rmode-=4;
-
- sprintf(buf,"/usr/prman/prman %s/plot3dp.rib",home);
- system(buf);
-
- [window setTitle:"3D"];
-
- return self;
- }
-
- - setAmbLight:sender
- {
- [ambLight setIntensity:ambient=[sender floatValue]];
- [self display];
- return self;
- }
-
- - setLight:sender
- {
- [aLight setIntensity:[sender floatValue]];
- [self display];
- return self;
- }
-
- -setLightX:sender
- {
- RtPoint from;
- lchi= -[sender floatValue];
- from[0]= LRAD*sin(lchi)*cos(ltheta);
- from[2]= LRAD*cos(lchi)*cos(ltheta);
- from[1]= LRAD*sin(ltheta);
- [aLight setFrom:from];
- [self display];
- return self;
- }
-
- -setLightY:sender
- {
- RtPoint from;
- ltheta=[sender floatValue];
- from[0]= LRAD*sin(lchi)*cos(ltheta);
- from[2]= LRAD*cos(lchi)*cos(ltheta);
- from[1]= LRAD*sin(ltheta);
- [aLight setFrom:from];
- [self display];
- return self;
- }
-
- - setMode:sender
- {
- int i;
-
- Rmode=i=[sender selectedRow];
- switch(i) {
- case 0:
- [self setSurfaceTypeForAll:N3D_PointCloud chooseHider:YES];
- [window setDepthLimit:NX_TwoBitGrayDepth];
- break;
- case 1:
- [self setSurfaceTypeForAll:N3D_WireFrame chooseHider:YES];
- [window setDepthLimit:NX_TwoBitGrayDepth];
- break;
- case 2:
- [self setSurfaceTypeForAll:N3D_FacetedSolids chooseHider:YES];
- break;
- case 3:
- [self setSurfaceTypeForAll:N3D_SmoothSolids chooseHider:YES];
- break;
- }
- [shape setData:pref :Rmode :Rflags];
- [self display];
- return self;
- }
-
- -setOverlay:sender
- {
- Omode=0;
- if ([[sender cellAt:0 :0] intValue]) Omode+=OVER_surf;
- if ([[sender cellAt:1 :0] intValue]) Omode+=OVER_csurf;
- if ([[sender cellAt:2 :0] intValue]) Omode+=OVER_base;
-
- [shape setOver:Omode];
- return self;
- }
-
- -printPSCode:sender
- {
-
- [self makeSMap:self];
- Rmode+=4;
- [shape setData:pref :Rmode :Rflags];
- [super printPSCode:sender];
- Rmode-=4;
- [shape setData:pref :Rmode :Rflags];
- return self;
- }
-
- -setFlags:sender
- {
- Rflags=0;
- if ([[flagSel findCellWithTag:0] intValue]) Rflags+=RF_axis;
- if ([[flagSel findCellWithTag:1] intValue]) Rflags+=RF_backs;
- if ([[flagSel findCellWithTag:2] intValue]) Rflags+=RF_floor;
- if ([[flagSel findCellWithTag:3] intValue]) Rflags+=RF_ticks;
- if ([[flagSel findCellWithTag:4] intValue]) Rflags+=RF_planes;
- if ([[flagSel findCellWithTag:5] intValue]) Rflags+=RF_labels;
- [shape setData:pref :Rmode :Rflags];
- [self display];
- return self;
- }
-
- -setFlagColor:sender
- {
- int i;
-
- i=[sender tag];
- NXConvertColorToRGB([sender color],
- &flagcol[i][0],&flagcol[i][1],&flagcol[i][2]);
- [shape setFlagColors:flagcol];
- [self display];
- return self;
- }
-
- -size320:sender
- {
- [[self window] sizeWindow:325 :204];
- return self;
- }
-
- -setEye:sender
- {
- RtPoint fromP = {0,0,6.0},toP={0.0,0.0,0.0};
- RtMatrix mx = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.0 };
-
- fromP[2]=[sender floatValue];
- [self setEyeAt:fromP toward:toP roll:0.0];
- mx[0][0]=mx[1][1]=mx[2][2]=3.0/fromP[2];
- [self setPreTransformMatrix:mx];
- [self display];
- return self;
- }
-
- -setAsp:sender
- {
- aspect=[sender floatValue];
- [shape setAng:theta :chi :aspect :ambient];
- [self display];
- return self;
- }
-
- -setProj:sender
- {
- if ([sender intValue]) {
- [self setProjection:N3D_Perspective];
- Rflags|=RF_persp;
- [self setUsePreTransformMatrix:NO];
- }
- else {
- [self setProjection:N3D_Orthographic];
- Rflags&=(~RF_persp);
- [self setUsePreTransformMatrix:YES];
- }
- [self display];
- return self;
- }
-
- -(float)getTheta
- {
- return(theta);
- }
-
- -(float)getChi
- {
- return(chi);
- }
-
- -aspect11:sender
- {
- [aspectS setFloatValue:1.0];
- aspect=1.0;
- [shape setAng:theta :chi :aspect :ambient];
- [self display];
- return self;
- }
- @end
-